home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 126-150 / disk_134 / dme / text1.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  16KB  |  949 lines

  1.  
  2. /*
  3.  * TEXT1.C
  4.  *
  5.  *    (C)Copyright 1987 by Matthew Dillon,    All Rights Reserved
  6.  */
  7.  
  8. #include "defs.h"
  9.  
  10. #define nomemory()  { memoryfail = 1; }
  11.  
  12. char RecallBuf[256];
  13.  
  14. setpen(line)
  15. {
  16.     register short pen = (Ep == BEp && line >= BSline && line <= BEline) ? 2 : 1;
  17.     if (Comlinemode)
  18.     pen = 1;
  19.     if (pen != Rp->FgPen)
  20.     SetAPen(Rp, pen);
  21. }
  22.  
  23. text_init()
  24. {
  25.     register ED *e;
  26.     register ED *ep = Ep;
  27.  
  28.     text_switch(NULL);
  29.     e = (ED *)allocb(sizeof(ED));
  30.     if (e == NULL)
  31.     return(0);
  32.     bzero(e, sizeof(ED));
  33.     e->Win = Win;
  34.     if (ep) {
  35.     e->Insertmode = ep->Insertmode;
  36.     e->Tabstop    = ep->Tabstop;
  37.     e->Wordwrap   = ep->Wordwrap;
  38.     } else {
  39.     e->Insertmode = 1;
  40.     e->Tabstop = 4;
  41.     }
  42.     e->Lines = 1;
  43.     e->Maxlines = 32;
  44.     e->List = (ubyte **)allocl(e->Maxlines);
  45.     e->List[0] = allocb(1);
  46.     e->List[0][0] = Current[0] = Clen = 0;
  47.     e->IWiny = 16;
  48.     e->dirlock = (ep) ? ep->dirlock : Dirlock;
  49.     llink(&Base, e);
  50.     strcpy(e->Name, "unnamed");
  51.     Ep = e;
  52.     text_cursor(1);
  53.     return(1);
  54. }
  55.  
  56.  
  57. text_switch(win)
  58. WIN *win;
  59. {
  60.     register ED *e;
  61.  
  62.     if (win)
  63.     text_sync();
  64.     if (win) {
  65.     for (e = Base; e; e = e->next) {
  66.         if (e->Win == win) {
  67.         Ep = e;
  68.         Win = win;
  69.         Rp = Win->RPort;
  70.         text_load();
  71.         if (!Ep->iconmode) {
  72.             set_window_params();
  73.             window_title();
  74.         }
  75.         return(1);
  76.         }
  77.     }
  78.     return(0);
  79.     }
  80. }
  81.  
  82.  
  83. text_sync()
  84. {
  85.     register ED *ep = Ep;
  86.     char redraw = 0;
  87.     short len;
  88.     ubyte *ptr;
  89.  
  90.     for (len = strlen(Current) - 1; len >= 0 && Current[len] == ' '; --len)
  91.     Current[len] = '\0';
  92.     Clen = len + 1;
  93.     if (!Comlinemode) {
  94.     if (strlen(ep->List[ep->Line]) != Clen) {
  95.         if (ptr = allocb(Clen+1)) {
  96.         ep->Modified = 1;
  97.         Overide = 0;
  98.         FreeMem(ep->List[ep->Line], strlen(ep->List[ep->Line])+1);
  99.         ep->List[ep->Line] = ptr;
  100.         } else {
  101.         nomemory();
  102.         strcpy(Current, ep->List[ep->Line]);
  103.         Clen = strlen(Current);
  104.         }
  105.     } else {
  106.         if (strcmp(ep->List[ep->Line], Current)) {
  107.         ep->Modified = 1;
  108.         Overide = 0;
  109.         }
  110.     }
  111.     strcpy(ep->List[ep->Line], Current);
  112.     }
  113.     if (Nsu == 0) {
  114.     if (ep->Column - ep->Topcolumn >= Columns || ep->Column < ep->Topcolumn) {
  115.         redraw = 1;
  116.         ep->Topcolumn = ep->Column - (Columns>>1);
  117.         if (ep->Topcolumn < 0)
  118.         ep->Topcolumn = 0;
  119.     }
  120.     if (ep->Line - ep->Topline >= Rows || ep->Line < ep->Topline) {
  121.         redraw = 1;
  122.         ep->Topline = ep->Line - (Rows>>1);
  123.         if (ep->Topline < 0)
  124.         ep->Topline = 0;
  125.     }
  126.     }
  127.     while (ep->Column > Clen)
  128.     Current[Clen++] = ' ';
  129.     Current[Clen] = '\0';
  130.     if (redraw)
  131.     text_redisplay();
  132.     return((int)redraw);
  133. }
  134.  
  135. text_load()
  136. {
  137.     if (Comlinemode)
  138.     return(0);
  139.     strcpy(Current, Ep->List[Ep->Line]);
  140.     Clen = strlen(Current);
  141.     while (Ep->Column > Clen)
  142.     Current[Clen++] = ' ';
  143.     Current[Clen] = '\0';
  144. }
  145.  
  146. text_colno()
  147. {
  148.     return(Ep->Column);
  149. }
  150.  
  151. text_lineno()
  152. {
  153.     return(Ep->Line+1);
  154. }
  155.  
  156. text_lines()
  157. {
  158.     return(Ep->Lines);
  159. }
  160.  
  161. text_cols()
  162. {
  163.     return((int)Clen);
  164. }
  165.  
  166. text_imode()
  167. {
  168.     return(Ep->Insertmode);
  169. }
  170.  
  171. text_tabsize()
  172. {
  173.     return((int)Ep->Tabstop);
  174. }
  175.  
  176. ubyte *
  177. text_name()
  178. {
  179.     return(Ep->Name);
  180. }
  181.  
  182. text_uninit()
  183. {
  184.     register int i;
  185.     register ED *ep = Ep;
  186.  
  187.     freelist(ep->List, ep->Lines);
  188.     FreeMem(ep->List, ep->Maxlines * sizeof(char *));
  189.  
  190.     if (BEp == ep) {
  191.     BEp = NULL;
  192.     BSline = BEline = -1;
  193.     }
  194.     lunlink(ep);
  195.     FreeMem(ep, sizeof(ED));
  196.     if (Base) {
  197.     Ep = Base;
  198.     text_load();
  199.     } else {
  200.     Ep = NULL;
  201.     }
  202. }
  203.  
  204. inversemode(n)
  205. {
  206.     if (n) {
  207.     SetAPen(Rp, 3);
  208.     SetDrMd(Rp, JAM2|INVERSVID);
  209.     } else {
  210.     setpen(Ep->Line);
  211.     SetDrMd(Rp, JAM2);
  212.     }
  213. }
  214.  
  215. text_cursor(n)
  216. {
  217.     movetocursor();
  218.     inversemode(n);
  219.     if (Current[Ep->Column])
  220.     Text(Rp, Current+Ep->Column, 1);
  221.     else
  222.     Text(Rp, " ", 1);
  223.     inversemode(0);
  224. }
  225.  
  226.  
  227. text_position(col, row)
  228. {
  229.     register ED *ep = Ep;
  230.     text_sync();
  231.     if (col == 0)
  232.     col = -1;
  233.     ep->Column = ep->Topcolumn + col;
  234.     if (ep->Column > 254)
  235.     ep->Column = 254;
  236.     if (ep->Column < 0)
  237.     ep->Column = 0;
  238.     ep->Line = ep->Topline + row;
  239.     if (ep->Line >= ep->Lines)
  240.     ep->Line = ep->Lines - 1;
  241.     if (ep->Line < 0)
  242.     ep->Line = 0;
  243.     text_load();
  244.     text_sync();
  245. }
  246.  
  247. displayblock(on)
  248. {
  249.     register long start = Ep->Topline;
  250.     register long lines = BEline - BSline + 1;
  251.  
  252.     if (start < BSline)
  253.     start = BSline;
  254.     if (!on) {
  255.     BSline = BEline = -1;
  256.     BEp = NULL;
  257.     }
  258.     if (Ep == BEp)
  259.     text_displayseg(start - Ep->Topline, lines);
  260. }
  261.  
  262. text_redrawblock(ok)
  263. {
  264.     WIN *savewin = NULL;
  265.  
  266.     if (BEp) {
  267.     if (BEp != Ep) {
  268.         savewin = Ep->Win;
  269.         text_switch(BEp->Win);
  270.     }
  271.     if (BSline <= BEline && BSline >= 0 && BEline < Ep->Lines) {
  272.         if (!ok) {
  273.         BEp = NULL;
  274.         BSline = BEline = -1;
  275.         }
  276.         text_displayseg(0, Rows);
  277.     }
  278.     if (savewin)
  279.         text_switch(savewin);
  280.     }
  281.     if (!ok) {
  282.     BEp = NULL;
  283.     BSline = BEline = -1;
  284.     }
  285. }
  286.  
  287. text_displayseg(start, n)
  288. {
  289.     register short i, c;
  290.     register ubyte *ptr;
  291.     register ED *ep = Ep;
  292.     char ib;
  293.  
  294.     if (Nsu)
  295.     return(0);
  296.     for (i = start; i < start + n && i < Rows && ep->Topline + i < ep->Lines; ++i) {
  297.     if (Comlinemode) {
  298.         if (ep->Topline + i != ep->Line)
  299.         continue;
  300.         ptr = Current;
  301.         SetAPen(Rp, 1);
  302.     } else {
  303.         ptr = ep->List[ep->Topline + i];
  304.         setpen(i+ep->Topline);
  305.     }
  306.     for (c = ep->Topcolumn; c && *ptr; ++ptr, --c);
  307.     c = strlen(ptr);
  308.     if (c) {
  309.         Move(Rp, COLT(0), ROWT(i));
  310.         Text(Rp, ptr, (c > Columns) ? Columns : c);
  311.     }
  312.     }
  313. }
  314.  
  315. text_redisplay()
  316. {
  317.     if (Nsu)
  318.     return(0);
  319.     SetAPen(Rp, 0);
  320.     if (Comlinemode)
  321.     RectFill(Rp, COL(0), ROW(Rows-1), Xbase+Xpixs, Ybase+Ypixs);
  322.     else
  323.     RectFill(Rp, Xbase, Ybase, Xbase + Xpixs, Ybase + Ypixs);
  324.     text_displayseg(0,Rows);
  325. }
  326.  
  327. text_redisplaycurrline()
  328. {
  329.     int row = Ep->Line - Ep->Topline;
  330.  
  331.     if (Nsu)
  332.     return(0);
  333.     SetAPen(Rp, 0);
  334.     RectFill(Rp, COL(0), ROW(row), Xbase+Xpixs, ROW(row+1)-1);
  335.     text_displayseg(row, 1);
  336. }
  337.  
  338. text_write(str)
  339. ubyte *str;
  340. {
  341.     register short len = strlen(str);
  342.     register short i;
  343.     register ED *ep = Ep;
  344.  
  345.     if (Clen + len >= 255) {
  346.     text_sync();
  347.     text_load();
  348.     }
  349.     if (ep->Insertmode == 0) {
  350.     i = len;
  351.     if (ep->Column + len < 255) {
  352.         bmov(str, Current + ep->Column, len);
  353.         if (ep->Column + len >= Clen)
  354.         Clen = ep->Column + len;
  355.         Current[Clen] = 0;
  356.         goto bin;
  357.     }
  358.     goto ok;
  359.     }
  360.     if (Clen + len < 255) {
  361.     bmov(Current + ep->Column, Current + ep->Column + len, Clen+1-ep->Column);
  362.     bmov(str, Current + ep->Column, len);
  363.     Clen += len;
  364.     ScrollRaster(Rp, -len * Xsize, 0 ,
  365.         COL(ep->Column - ep->Topcolumn), ROW(ep->Line - ep->Topline),
  366.         COL(Columns) - 1, ROW(ep->Line - ep->Topline + 1) - 1
  367.     );
  368.     i = (ep->Column - ep->Topcolumn + len > Columns) ? Columns - ep->Column + ep->Topcolumn : len;
  369. bin:
  370.     setpen(ep->Line);
  371.     Move(Rp, COLT(ep->Column - ep->Topcolumn), ROWT(ep->Line - ep->Topline));
  372.     Text(Rp, str, i);
  373.     ep->Column += len;
  374.     if (ep->Column - ep->Topcolumn >= Columns)
  375.         text_sync();
  376.     }
  377. ok:
  378.     if (Comlinemode == 0 && ep->Wordwrap)
  379.     do_reformat(0);
  380. }
  381.  
  382.  
  383. do_up()
  384. {
  385.     if (Ep->Line) {
  386.     text_sync();
  387.     --Ep->Line;
  388.     text_load();
  389.     if (Ep->Line < Ep->Topline) {
  390.         if (Nsu == 0) {
  391.         ScrollRaster(Rp,0,-Ysize,COL(0),ROW(0),COL(Columns)-1,ROW(Rows)-1);
  392.         --Ep->Topline;
  393.         text_displayseg(0, 1);
  394.         }
  395.     }
  396.     } else {
  397.     Abortcommand = 1;
  398.     }
  399. }
  400.  
  401. do_scrolldown()
  402. {
  403.     if (Ep->Topline + Rows < Ep->Lines) {
  404.     if (Nsu == 0) {
  405.         text_sync();
  406.         ScrollRaster(Rp,0,Ysize,COL(0),ROW(0),COL(Columns)-1,ROW(Rows)-1);
  407.         ++Ep->Topline;
  408.         ++Ep->Line;
  409.         text_load();
  410.         text_displayseg(Rows-1, 1);
  411.     }
  412.     } else {
  413.     Abortcommand = 1;
  414.     }
  415. }
  416.  
  417. do_scrollup()
  418. {
  419.     if (Ep->Topline) {
  420.     if (Nsu == 0) {
  421.         text_sync();
  422.         ScrollRaster(Rp,0,-Ysize,COL(0),ROW(0),COL(Columns)-1,ROW(Rows)-1);
  423.         --Ep->Topline;
  424.         --Ep->Line;
  425.         text_load();
  426.         text_displayseg(0, 1);
  427.     }
  428.     } else {
  429.     Abortcommand = 1;
  430.     }
  431. }
  432.  
  433. do_down()
  434. {
  435.     if (Ep->Line + 1 < Ep->Lines) {
  436.     text_sync();
  437.     ++Ep->Line;
  438.     text_load();
  439.     if (Ep->Line - Ep->Topline >= Rows) {
  440.         if (Nsu == 0) {
  441.         ScrollRaster(Rp,0,Ysize,COL(0),ROW(0),COL(Columns)-1,ROW(Rows)-1);
  442.         ++Ep->Topline;
  443.         text_displayseg(Rows-1, 1);
  444.         }
  445.     }
  446.     } else {
  447.     Abortcommand = 1;
  448.     }
  449. }
  450.  
  451. /*
  452.  *  PAGEUP
  453.  *  PAGEDOWN
  454.  *  PAGESET n    (n = 0 to 100 for percentage of #rows to scroll, minimum 1)
  455.  *        can be > 100.
  456.  */
  457.  
  458. do_page()
  459. {
  460.     register int n, multiplier = 1;
  461.     register ED *ep = Ep;
  462.     static short pctg = 80;
  463.  
  464.     switch(av[0][4]) {
  465.     case 'u':
  466.     multiplier = -1;
  467.     case 'd':
  468.     n = multiplier * Rows * pctg / 100;
  469.     if (!n)
  470.         n = multiplier;
  471.     if (n > 0 && ep->Topline >= ep->Lines - Rows)
  472.         return(0);
  473.     text_sync();
  474.     ep->Line += n;
  475.     ep->Topline += n;
  476.     if (ep->Line >= ep->Lines)
  477.         ep->Line = ep->Lines - 1;
  478.     if (ep->Line < 0)
  479.         ep->Line = 0;
  480.     if (ep->Topline >= ep->Lines)
  481.         ep->Topline = ep->Lines - Rows - 1;
  482.     if (ep->Topline < 0)
  483.         ep->Topline = 0;
  484.     text_load();
  485.     if (!text_sync())
  486.         text_redisplay();
  487.     break;
  488.     case 's':
  489.     pctg = atoi(av[1]);
  490.     break;
  491.     }
  492. }
  493.  
  494.  
  495. do_downadd()
  496. {
  497.     ubyte *ptr;
  498.  
  499.     if (Ep->Line + 1 == Ep->Lines) {
  500.     Ep->Modified = 1;
  501.     if (makeroom(32) && (ptr = allocb(1))) {
  502.         Ep->List[Ep->Lines] = ptr;
  503.         *ptr = 0;
  504.         ++Ep->Lines;
  505.     } else {
  506.         nomemory();
  507.     }
  508.     }
  509.     do_down();
  510. }
  511.  
  512.  
  513. do_left()
  514. {
  515.     if (Ep->Column) {
  516.     --Ep->Column;
  517.     if (Ep->Column < Ep->Topcolumn)
  518.         text_sync();
  519.     } else {
  520.     Abortcommand = 1;
  521.     }
  522. }
  523.  
  524. do_right()
  525. {
  526.     if (Ep->Column != 254) {
  527.     if (Current[Ep->Column] == 0) {
  528.         Current[Ep->Column] = ' ';
  529.         Current[Ep->Column+1]= '\0';
  530.         ++Clen;
  531.     }
  532.     ++Ep->Column;
  533.     if (Ep->Column - Ep->Topcolumn >= Columns)
  534.         text_sync();
  535.     } else {
  536.     Abortcommand = 1;
  537.     }
  538. }
  539.  
  540. do_tab()
  541. {
  542.     register short n;
  543.  
  544.     for (n = Ep->Tabstop-(Ep->Column % Ep->Tabstop); n > 0; --n)
  545.     do_right();
  546. }
  547.  
  548. do_backtab()
  549. {
  550.     register short n;
  551.  
  552.     n = Ep->Column % Ep->Tabstop;
  553.     if (!n)
  554.     n = Ep->Tabstop;
  555.     for (; n > 0; --n)
  556.     do_left();
  557. }
  558.  
  559. do_return()
  560. {
  561.     ubyte buf[256];
  562.     char *partial;
  563.  
  564.     if (Comlinemode) {
  565.     strcpy(buf, Current);
  566.     strcpy(RecallBuf, Current);
  567.     partial = Partial;
  568.     Partial = NULL;
  569.     escapecomlinemode();
  570.     if (partial) {
  571.         if (do_command(buf))
  572.         do_command(partial);
  573.         free(partial);
  574.     } else {
  575.         do_command(buf);
  576.     }
  577.     } else {
  578.     Ep->Column = 0;
  579.     text_sync();
  580.     do_downadd();
  581.     }
  582. }
  583.  
  584. do_bs()
  585. {
  586.     register ED *ep = Ep;
  587.     if (ep->Column) {
  588.     bmov(Current + ep->Column, Current + ep->Column - 1, Clen - ep->Column + 1);
  589.     --ep->Column;
  590.     --Clen;
  591.     if (ep->Column < ep->Topcolumn) {
  592.         text_sync();
  593.     } else {
  594.         ScrollRaster(Rp, Xsize, 0,
  595.         COL(ep->Column - ep->Topcolumn),
  596.         ROW(ep->Line   - ep->Topline),
  597.         COL(Columns)-1,
  598.         ROW(ep->Line - ep->Topline + 1)-1
  599.         );
  600.         if (Clen >= ep->Topcolumn + Columns) {
  601.         setpen(ep->Line);
  602.         Move(Rp, COLT(Columns-1), ROWT(ep->Line - ep->Topline));
  603.         Text(Rp, Current + ep->Topcolumn + Columns - 1, 1);
  604.         }
  605.     }
  606.     if (Comlinemode == 0 && ep->Wordwrap)
  607.         do_reformat(0);
  608.     } else {
  609.     Abortcommand = 1;
  610.     }
  611. }
  612.  
  613.  
  614. /*
  615.  * esc, escimm
  616.  */
  617.  
  618. int Savetopline, Savecolumn, Savetopcolumn;
  619.  
  620. do_recall()
  621. {
  622.     av[0] = (ubyte *)"escimm";
  623.     av[1] = (ubyte *)RecallBuf;
  624.     do_esc();
  625. }
  626.  
  627. do_esc()
  628. {
  629.     register ED *ep = Ep;
  630.  
  631.     if (Comlinemode)
  632.     return(escapecomlinemode());
  633.     text_sync();
  634.     if (av[0][3] == 'i')
  635.     strcpy(Current, av[1]);
  636.     else
  637.     Current[0] = 0;
  638.     Clen = strlen(Current);
  639.     Comlinemode = 1;
  640.     returnoveride(1);
  641.     Savetopline = ep->Topline;
  642.     Savecolumn    = ep->Column;
  643.     Savetopcolumn = ep->Topcolumn;
  644.     ep->Column      = Clen;
  645.     ep->Topcolumn = 0;
  646.     ep->Topline   = ep->Line - Rows + 1;
  647.     SetAPen(Rp, 0);
  648.     RectFill(Rp, COL(0), ROW(Rows-1), Xbase+Xpixs, Ybase+Ypixs);
  649.     SetAPen(Rp, 1);
  650.     Move(Rp, COL(0), ROW(Rows-1) - 1);
  651.     Draw(Rp, Xbase + Xpixs, ROW(Rows-1) - 1);
  652.     text_displayseg(Rows-1,1);
  653. }
  654.  
  655.  
  656. escapecomlinemode()
  657. {
  658.     register ED *ep = Ep;
  659.  
  660.     if (Partial) {
  661.     free(Partial);
  662.     Partial = NULL;
  663.     }
  664.     if (Comlinemode) {
  665.     strcpy(RecallBuf, Current);
  666.     Comlinemode = 0;
  667.     returnoveride(0);
  668.     ep->Topline = Savetopline;
  669.     ep->Column  = Savecolumn;
  670.     ep->Topcolumn = Savetopcolumn;
  671.     text_load();
  672.     SetAPen(Rp, 0);
  673.     RectFill(Rp, COL(0), ROW(Rows-1)-1, Xbase+Xpixs, Ybase+Ypixs);
  674.     SetAPen(Rp, 1);
  675.     text_displayseg(Rows-2,2);
  676.     }
  677. }
  678.  
  679.  
  680. do_del()
  681. {
  682.     register ED *ep = Ep;
  683.  
  684.     if (Current[ep->Column]) {
  685.     bmov(Current + ep->Column + 1, Current + ep->Column, Clen - ep->Column);
  686.     --Clen;
  687.     ScrollRaster(Rp, Xsize, 0,
  688.         COL(ep->Column - ep->Topcolumn),
  689.         ROW(ep->Line - ep->Topline),
  690.         COL(Columns)-1,
  691.         ROW(ep->Line - ep->Topline + 1) - 1
  692.     );
  693.     if (Clen >= ep->Topcolumn + Columns) {
  694.         setpen(ep->Line);
  695.         Move(Rp, COLT(Columns-1), ROWT(ep->Line-ep->Topline));
  696.         Text(Rp, Current+ep->Topcolumn+Columns-1, 1);
  697.     }
  698.     if (Comlinemode == 0 && ep->Wordwrap)
  699.         do_reformat(0);
  700.     }
  701. }
  702.  
  703. do_top()
  704. {
  705.     text_sync();
  706.     Ep->Line = 0;
  707.     text_load();
  708.     text_sync();
  709. }
  710.  
  711. do_bottom()
  712. {
  713.     text_sync();
  714.     Ep->Line = Ep->Lines - 1;
  715.     text_load();
  716.     text_sync();
  717. }
  718.  
  719. do_firstcolumn()
  720. {
  721.     if (Ep->Column) {
  722.     Ep->Column = 0;
  723.     text_sync();
  724.     }
  725. }
  726.  
  727. do_firstnb()
  728. {
  729.     for (Ep->Column = 0; Current[Ep->Column] == ' '; ++Ep->Column);
  730.     if (Current[Ep->Column] == 0)
  731.     Ep->Column = 0;
  732.     text_sync();
  733. }
  734.  
  735. do_lastcolumn()
  736. {
  737.     short i;
  738.  
  739.     text_sync();
  740.     i = (Comlinemode) ? Clen : strlen(Ep->List[Ep->Line]);
  741.     if (i != Ep->Column) {
  742.     Ep->Column = i;
  743.     text_sync();
  744.     }
  745. }
  746.  
  747. /*
  748.  * GOTO [+/-]N
  749.  * GOTO BLOCK    start of block
  750.  * GOTO START    start of block
  751.  * GOTO END    end of block
  752.  */
  753.  
  754. do_goto()
  755. {
  756.     register short n, i;
  757.     register ubyte *ptr = av[1];
  758.  
  759.     i = 0;
  760.     n = -1;
  761.  
  762.     switch(*ptr) {
  763.     case 'b':
  764.     case 's':
  765.     case 'B':
  766.     case 'S':
  767.     n = -1;
  768.     if (Ep == BEp)
  769.         n = BSline;
  770.     break;
  771.     case 'e':
  772.     case 'E':
  773.     n = -1;
  774.     if (Ep == BEp)
  775.         n = BEline;
  776.     break;
  777.     case '+':
  778.     i = 1;
  779.     case '-':
  780.     n = Ep->Line;
  781.     default:
  782.     n += atoi(ptr+i);
  783.     }
  784.     if (n >= Ep->Lines)
  785.     n = Ep->Lines - 1;
  786.     if (n < 0)
  787.     n = 0;
  788.     text_sync();
  789.     Ep->Line = n;
  790.     text_load();
  791.     text_sync();
  792. }
  793.  
  794. do_screentop()
  795. {
  796.     text_sync();
  797.     Ep->Line = Ep->Topline;
  798.     text_load();
  799.     text_sync();
  800. }
  801.  
  802. do_screenbottom()
  803. {
  804.     text_sync();
  805.     Ep->Line = Ep->Topline + Rows - 1;
  806.     if (Ep->Line < 0 || Ep->Line >= Ep->Lines)
  807.     Ep->Line = Ep->Lines - 1;
  808.     text_load();
  809.     text_sync();
  810. }
  811.  
  812. static ubyte Fstr[256];
  813. static ubyte Rstr[256];
  814. static short Srch_sign;
  815. static char Doreplace;
  816.  
  817. /*
  818.  * findstr, repstr
  819.  */
  820.  
  821. do_findstr()
  822. {
  823.     if (av[0][0] == 'f')
  824.     strcpy(Fstr, av[1]);
  825.     else
  826.     strcpy(Rstr, av[1]);
  827. }
  828.  
  829. /*
  830.  * findr, nextr, prevr
  831.  */
  832.  
  833. do_findr()
  834. {
  835.     Doreplace = 1;
  836.     Srch_sign = 1;
  837.     switch(av[0][0]) {
  838.     case 'f':
  839.     strcpy(Fstr, av[1]);
  840.     strcpy(Rstr, av[2]);
  841.     break;
  842.     case 'p':
  843.     Srch_sign = -1;
  844.     break;
  845.     }
  846.     search_operation();
  847. }
  848.  
  849. /*
  850.  * find, next, prev
  851.  */
  852.  
  853. do_find()
  854. {
  855.     Doreplace = 0;
  856.     Srch_sign = 1;
  857.     switch(av[0][0]) {
  858.     case 'f':
  859.     strcpy(Fstr, av[1]);
  860.     break;
  861.     case 'p':
  862.     Srch_sign = -1;
  863.     break;
  864.     }
  865.     search_operation();
  866. }
  867.  
  868.  
  869. void
  870. search_operation()
  871. {
  872.     int flen = strlen(Fstr);
  873.     int rlen = strlen(Rstr);
  874.     char senabled = 0;
  875.     register ubyte *ptr;
  876.     register int i, col;
  877.     register ED *ep = Ep;
  878.  
  879.     text_sync();
  880.     if (!flen) {
  881.     title("No find pattern");
  882.     Abortcommand = 1;
  883.     return;
  884.     }
  885.  
  886.     col = ep->Column;
  887.     if (col >= strlen(ep->List[ep->Line]))
  888.     col = strlen(ep->List[ep->Line]);
  889.     for (i = ep->Line;;) {
  890.     ptr = ep->List[i];
  891.     if (Srch_sign > 0) {
  892.         while (ptr[col]) {
  893.         if (Fstr[0] == ptr[col] &&
  894.         strncmp(Fstr,ptr+col,flen) == 0 &&
  895.         senabled) {
  896.             goto found;
  897.         }
  898.         senabled = 1;
  899.         ++col;
  900.         }
  901.         senabled = 1;
  902.         if (++i >= ep->Lines)
  903.         break;
  904.         col = 0;
  905.     } else {
  906.         while (col >= 0) {
  907.         if (Fstr[0] == ptr[col] &&
  908.         strncmp(Fstr,ptr+col,flen) == 0 &&
  909.         senabled) {
  910.             goto found;
  911.         }
  912.         senabled = 1;
  913.         --col;
  914.         }
  915.         senabled = 1;
  916.         if (--i < 0)
  917.         break;
  918.         col = strlen(ep->List[i]);
  919.     }
  920.     }
  921.     title("Pattern Not Found");
  922.     Abortcommand = 1;
  923.     return;
  924.  
  925. found:
  926.     ep->Line = i;
  927.     ep->Column = col;
  928.  
  929.     text_load();
  930.     if (Doreplace) {
  931.     if (rlen > flen && rlen-flen+strlen(ptr) > 254) {
  932.         title("Replace: Line Too Long");
  933.         Abortcommand = 1;
  934.         return;
  935.     }
  936.     if (Clen-col-flen >= 0) {
  937.         bmov(Current+col+flen, Current+col+rlen, Clen-col-flen+1);
  938.         bmov(Rstr, Current+col, rlen);
  939.         Clen += rlen-flen;
  940.     }
  941.     text_sync();
  942.     text_redisplaycurrline();
  943.     } else {
  944.     text_sync();
  945.     }
  946. }
  947.  
  948.  
  949.